package com.qf.gateway.filter;

import com.qf.gateway.service.AuthService;
import com.qf.gateway.utils.EncryptUtil;
import com.qf.gateway.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Comparator;

/**
 * 认证过滤器:
 *      租户认证
 *      第三方系统对接认证
 *      管理员认证
 * @author 千锋健哥
 */
@Component
public class AuthFilter implements Ordered, GlobalFilter {

    @Autowired
    private AuthService authService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1. 获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        //2. 获取响应对象
        ServerHttpResponse response = exchange.getResponse();

        //3. 判断用户的访问路径, 如果是租户注册, 租户认证, 租户发送短信验证码
        //如果是管理员认证, 这些路径都无条件放行
        String path = request.getURI().getPath();

        //放行的路径
        if (path.contains("/user")
                || path.contains("/auth/checkcode/send")
                || path.contains("/auth/tenant/regist")
                || path.contains("/auth/tenant/login")) {
            return chain.filter(exchange);
        }

        //4. 判断是否为第三方系统对接路径, 如果是则处理第三方系统对接认证逻辑
        if (path.contains("/api")) {
            //4.1 判断accessKey, accessSecurit秘钥, sign签名 这些如果为空则抛出401权限不足异常
            String accessKey = request.getHeaders().getFirst("access-key");
            String accessSecurit = request.getHeaders().getFirst("access-securit");
            String sign = request.getHeaders().getFirst("sign");

            if (StringUtils.isEmpty(accessKey)
                    || StringUtils.isEmpty(accessSecurit)
                    || StringUtils.isEmpty(sign)) {
                //设置响应的状态码401, 权限不足
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }

            //4.2 判断sign令牌是否正确, 如果不正确则返回401权限不足异常
            String temp = accessKey + accessSecurit;
            boolean valid = EncryptUtil.valid(temp, sign);
            if (valid) {
                //4.3 判断accessKey和accessSecurit秘钥是否正确, 正确则放行, 不正确在返回401权限不足异常.
                Boolean flag = authService.findByAccessKey(accessKey, accessSecurit);
                if (flag) {
                    //放行
                    return chain.filter(exchange);
                }
            }

        }

        //5. 如果是租户登录那么进行jwt校验
        String token = request.getHeaders().getFirst("token");
        if (!StringUtils.isEmpty(token)) {
            try {
                //6. 解析jwt
                Claims claims = JwtUtil.parseJWT(token);
                String subject = claims.getSubject();
                //7. 如果解析正确将解析后的内容放入当前请求的请求头中携带, 供其他微服务使用
                request.mutate().header("token", subject);
                return chain.filter(exchange);
            } catch (Exception e) {
                //throw new RuntimeException(e);
            }
        }

        //设置响应的状态码401, 权限不足
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        return response.setComplete();
    }

    @Override
    public int getOrder() {
        return 0;
    }

}
